home *** CD-ROM | disk | FTP | other *** search
- CrackLib: A ProActive Password Sanity Library
-
- By: Alec Muffett, 16th June, 1993
-
- Address: alec.muffett@uk.sun.com
- alec.muffett@sun.co.uk
- alec_muffett@hicom.lut.ac.uk
-
-
- - This software is not my fault in any way, nor indeed anybody's -
-
-
- *** What is CrackLib ***
-
-
- CrackLib is a library containing a C function (well, lots of functions
- really, but you only need to use one of them) which may be used in a
- "passwd"-like program.
-
- The idea is simple: try to prevent users from choosing passwords that
- could be guessed by "Crack" by filtering them out, at source.
-
- CrackLib is an offshoot of the the version 5 "Crack" software, and
- contains a considerable number of ideas nicked from the new software.
-
- At the time of writing, Crack 5 is incomplete (still awaiting purchase
- of my home box) - but I though I could share this with you.
-
- [ Incidentally, if Dell or anyone would like to "donate" a Linuxable
- 486DX2-66MHz box (EISA/16Mb RAM/640MB HD/AHA1740) as a development
- platform for Crack, I'd be more than grateful to hear from you. 8-) ]
-
-
- NOTE THIS WELL: CrackLib is NOT a replacement "passwd" program.
- CrackLib is a LIBRARY. CrackLib is what trendy marketdroid types would
- probably call an "enabler".
-
- The idea is that you wire it into your _own_ "passwd" program (if you
- have source); alternatively, you wire it into something like "shadow"
- from off of the net. You can use it in other things, too.
-
- You can use it almost _everywhere_.
-
-
- *** Advantages of CrackLib ***
-
-
- 1) it WORKS!
-
- I wrote something similar ("goodpass") a few years back, which went out
- with Crack v3.x.
-
- Goodpass was slow and buggy and I think it was used (at least in part)
- in "npasswd". Hopefully, CrackLib will supplant "goodpass" entirely.
-
-
- 2) it's FAST!
-
- CrackLib finds potential passwords quickly, by using an index file to
- access dictionary words, and by keeping a table to assist binary
- searching.
-
-
- 3) it's SMALL!
-
- CrackLib's dictionary is modified-DAWG compressed with a chunksize of 16
- words (see Crack v5.0 docs (when it comes out) for details) - and then
- the index file is built, with one entry per chunk.
-
- The upshot of all this is that CrackLib can do indexed, binary searches
- in a 1.4 million word dictionary (raw size ~ 15Mb), but the CrackLib
- files (data+index+watermarks) occupy only ~ 7Mb. (45% original size)
-
- It's even efficient over NFS !
-
-
- 4) it's MIND-NUMBINGLY THOROUGH!
-
- (is this beginning to read like a B-movie flyer, or what?)
-
- CrackLib makes literally hundreds of tests to determine whether you've
- chosen a bad password.
-
- * It tries to generate words from your username and gecos entry to tries
- to match them against what you've chosen.
-
- * It checks for simplistic patterns.
-
- * It then tries to reverse-engineer your password into a dictionary
- word, and searches for it in your dictionary.
-
- - after all that, it's PROBABLY a safe(-ish) password. 8-)
-
-
- *** Instructions for building CrackLib...
-
-
- STEP 0) Engage your brain.
-
- I'm interested in improving the CrackLib software, doing bugfixes,
- "guessing technique" improvements, and portability enhancements.
-
- I'm NOT interested in unhelpful comments like "well, _my_ operating
- system doesn't come with a dictionary". If it doesn't, either complain
- to your vendor, or GO AND GET a dictionary off the net.
-
- CrackLib is NOT a TOOL. It is not a complete package. It is not
- something you can utilise directly.
-
- It is a resource, an aid, something to enhance the functionality of
- other software. You need to (either) write OR modify other software to
- use it. If you can't do this, then you shouldn't be wasting your time
- with it.
-
- Regarding bugs and portability problems: please try to work them out for
- yourself, and then (please) TELL me about them. This will help me
- improve future versions.
-
-
- STEP 1) Edit the Makefile to set your preferred value of DICTPATH
-
- This it the directory+filename-prefix that your version of CrackLib will
- go hunting for, and it must be visible to all programs on all hosts that
- use CrackLib
-
- Hence, if you want to use a CrackLib binary on a distributed network,
- these files are probably best placed on an NFS server.
-
- Note: You have to specify a FILENAME PREFIX too, eg:
-
- DICTPATH=/usr/local/lib/pw_dict
-
- which will generate:
-
- /usr/local/lib/pw_dict.pwd
- /usr/local/lib/pw_dict.pwi
- /usr/local/lib/pw_dict.hwm
-
- which are the files that CrackLib needs.
-
- These files are NOT byte-order independent, in fact they are probably
- ARCHITECTURE SPECIFIC, mostly due to speed constraints. If this is a
- problem, I suggest you use:
-
- DICTPATH=/usr/local/lib/pw_dict.sun4
- DICTPATH=/usr/local/lib/pw_dict.i386
- DICTPATH=/usr/local/lib/pw_dict.cray
-
- ...etc, and build several sets of files, as appropriate.
-
-
- (Hackers Note: Strictly, only *.pwi and *.hwm should be architecture
- dependent; however, if you build two dictionaries on two different
- platforms, you MAY wind up with different *.pwd files too, due to
- incompatibilities in the std Unix utilities, or from using different
- SOURCEDICTs.
-
- I may try to work this out in the next release. In the mean time, if
- your *.pwd files are EXACTLY identical (use "cmp" to test), you can
- delete the multiple copies and use softlinks instead.)
-
-
- STEP 2) Add to the SOURCEDICT variable, any files continaing extra words
- that you wish CrackLib to use. CrackLib merges all of these files
- together, removes redundant characters, and compresses them. Generally,
- the output file is 40..60% the size of all the input files, combined.
-
- NOTE: THE DEFAULT VALUE OF "SOURCEDICT" CONTAINS "/usr/dict/words" -
- this is a file which can be found on many BSD-type Unix systems,
- containing a list of words, one per line, suitable for use with
- "cracklib". If you do not have such a file, refer to STEP 0.
-
-
- STEP 3) do:
-
- % make all
-
- then do:
-
- % make install
-
- which will build the CrackLib dictionary in $DICTPATH.
-
-
- *** NOTE THIS WELL ***
-
- If you supply massive amounts of text to CrackLib to use a a dictionary,
- you must have enough free space available for use by the "sort" command,
- when the dictionary is built.
-
- So: If you do not have (say) about 20Mb free in /usr/tmp (or whatever
- temporary area your "sort" command uses), have a look at the
- "util/mkdict" script.
-
- You can usually tweak the "sort" command to use any large area of disk
- you desire, by use of the "-T" option, and "mkdict" has a hook for this.
-
-
- STEP 4) Wire a call to "FascistCheck()" into your "passwd" program
-
-
- - Left as an exercise for the reader.
-
-
- *** Example of how to invoke CrackLib
-
- Insert a call to the routine FascistCheck, which is defined thusly:
-
- NAME
- FascistCheck - check a potential password for guessability
-
-
- SYNOPSIS
-
- char *FascistCheck(char *pw, char *dictpath);
-
-
- DESCRIPTION
-
- FascistCheck() takes 2 arguments:
-
- pw - a string continaing the users chosen "potential password"
-
- dictpath - the full path name + filename prefix of the
- CrackLib dictionary, specified in the installation Makefile.
- (If you still haven't sussed, I'm talking about DICTPATH).
-
-
- RETURN VALUE
-
- FascistCheck() returns the NULL pointer for a good password,
- or a pointer to a diagnostic string if it is a bad password.
-
-
- BUGS
- - it can't catch everything. Just most things.
-
- - it calls getpwuid(getuid()) to look up the user,
- this MAY affect poorly written programs
-
- - using more than one pw_dict file, eg:
-
- char *msg;
- if (msg = FascistCheck(pw, "onepath") ||
- msg = FascistCheck(pw, "anotherpath"))
- {
- printf("Bad Password: because %s\n", msg);
- }
-
- ...works, but it's a kludge. AVOID IT IF POSSIBLE.
- Using just the one dictionary is more efficient, anyway.
-
- - PWOpen() routines should cope with having more than 1
- dictionary open at a time. I'll fix this RSN.
-
-
- WORKED EXAMPLE
-
- ---- modified extract from BSD distribution - "local_passwd.c" ----
-
- #ifndef CRACKLIB_DICTPATH /* if possible, get from the same Makefile as CrackLib */
- #define CRACKLIB_DICTPATH "/usr/local/lib/pw_dict"
- #endif /* see examples on how to import DICTPATH into CRACKLIB_DICTPATH */
- ...
- ...
- ...
- for (buf[0] = '\0', tries = 0;;) {
- p = getpass("New password:");
- if (!*p) {
- (void)printf("Password unchanged.\n");
- pw_error(NULL, 0, 0);
- }
-
- #ifndef CRACKLIB_DICTPATH
- if (strlen(p) <= 5 && (uid != 0 || ++tries < 2)) {
- (void)printf("Please enter a longer password.\n");
- continue;
- }
- for (t = p; *t && islower(*t); ++t);
- if (!*t && (uid != 0 || ++tries < 2)) {
- (void)printf("Please don't use an all-lower case password.\nUnusual capitalization, control characters or digits are suggested.\n");
- continue;
- }
- #else
- {
- char *msg;
- if (msg = (char *) FascistCheck(pwbuf, CRACKLIB_DICTPATH)) {
- printf("Please use a different password.\n");
- printf("The one you have chosen is unsuitable because %s.\n", msg);
- continue; /* go round and round until they get it right */
- }
- }
- #endif /* CRACKLIB_DICTPATH */
-
- (void)strcpy(buf, p);
- if (!strcmp(buf, getpass("Retype new password:")))
- break;
- (void)printf("Mismatch; try again, EOF to quit.\n");
- }
- ---- end of extract ----
-